#!/usr/bin/env python
# coding: utf-8


import cv2
import numpy as np
import matplotlib.pyplot as plt




img = cv2.imread('lenna.jpg',1)

#print (img)

#显示图像
def my_show(img):
    plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
    # plt.show()

#my_show(img)




#Gaussian Kernel 高斯模糊  11 为卷积核大小  2为方差  卷积核核方差越大越模糊
g_img = cv2.GaussianBlur(img,(11,11),2)
# plt.subplot(121)
#my_show(img)
# plt.subplot(122)
#my_show(g_img)


kernel_1d = cv2.getGaussianKernel(11,2) #查看高斯卷积核
# print (kernel_1d)


g1_img = cv2.sepFilter2D(img,-1,kernel_1d,kernel_1d)


# laplacian 拉普拉斯

#拉普拉斯卷积核
kernel = np.array([[0,1,0],[1,-4,1],[0,1,0]])

#使用拉普拉斯算子进行卷积 二阶导数
lap_img = cv2.filter2D(img,-1,kernel)
#my_show(lap_img) #拉普拉斯卷积核 显示图像的边缘信息

g_img = cv2.GaussianBlur(img,(11,11),2)
# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(lap_img)



#加强版拉普拉斯算子
kernel_strong = np.array([[1,1,1],[1,-8,1],[1,1,1]])
lap_img = cv2.filter2D(img,-1,kernel_strong)


# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(lap_img)




# ## 图像锐化  即将提取出来的边缘信息加到原图中


kernel_strong = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]])
lap_img = cv2.filter2D(img,-1,kernel_strong)
# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(lap_img)




kernel_strong = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
lap_img = cv2.filter2D(img,-1,kernel_strong)
# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(lap_img)


#sobel算子 边缘更粗一些

y_kernel = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
sy_img = cv2.filter2D(img,-1,y_kernel)
# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(sy_img)




x_kernel = np.array([[-1,0,-1],[-2,0,2],[-1,0,1]])
sx_img = cv2.filter2D(img,-1,x_kernel)
# plt.subplot(121)
# my_show(img)
# plt.subplot(122)
# my_show(sx_img)




plt.figure(figsize=(10,10),dpi=120)
# plt.subplot(131)
# my_show(sy_img)
# plt.subplot(132)
# my_show(sx_img)
# plt.subplot(133)
# my_show(lap_img)


#  medianblur 中值滤波 过滤掉了最大值和最小值


md_img = cv2.medianBlur(img,7)
# plt.subplot(131)
# my_show(img)
# plt.subplot(132)
# my_show(md_img)
# plt.subplot(133)
# my_show(g_img)
# plt.show()




noise_img = cv2.imread('noisy_lenna.jpg',1)
my_show(noise_img)
#plt.show()

#中值滤波 可以轻松的处理掉雪花噪声
denoise_img = cv2.medianBlur(noise_img,7)
my_show(denoise_img)
#plt.show()



#用高斯滤波无法处理掉雪花噪声
denoise_img = cv2.GaussianBlur(noise_img,(3,3),2)
my_show(denoise_img)
# plt.show()




# Harris Corner 哈里斯角点

my_show(img)
#首先对图片进行灰度变
img_gray = (cv2.cvtColor(img,cv2.COLOR_BGR2GRAY))



def my_show_gray(img):
    plt.imshow(img,cmap='gray')
my_show_gray(img_gray)
#plt.show()



img_harris = cv2.cornerHarris(img_gray,2,3,0.03)


threshold = np.max(img_harris)*0.02

img = cv2.imread('lenna.jpg',1)
img[img_harris>threshold] = [0,0,255]#凡是值大于预值的 我们都可以认为是角点 对它们重新赋值 变成红色

my_show(img)
# plt.show()


img_t = cv2.imread('towers.jpg',1)
my_show(img_t)
# plt.show()

imgt_gray = (cv2.cvtColor(img_t,cv2.COLOR_BGR2GRAY)) #首先把彩图变成灰度图
imgt_harris = cv2.cornerHarris(imgt_gray,2,3,0.03)#通过计算 得到R的值
imgt_harris = cv2.dilate(imgt_harris,None) #膨胀操作

thresholdt = np.max(imgt_harris)*0.03
img_t[imgt_harris>thresholdt] = [0,0,255]
# plt.figure(figsize=(20,10),dpi=120)
my_show(img_t)
# plt.show()

#在灰度图上显示
thresholdt = np.max(imgt_harris)*0.03
imgt_gray[imgt_harris>thresholdt] = 255
plt.figure(figsize=(20,10),dpi=120)
my_show_gray(imgt_gray)
# plt.show()


# ## SIFT算法


print (cv2.__version__)

img = cv2.imread('lenna.jpg')
sift = cv2.xfeatures2d.SIFT_create() #创建SIFT对象
kp = sift.detect(img) #检测关键点


#print (kp)


kp, des = sift.compute(img,kp) #返回坐标和描述子
print(des.shape)
img_sift = cv2.drawKeypoints(img, kp, outImage=np.array([]),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

plt.figure(figsize=(10,10),dpi=100)
my_show(img_sift)
plt.show()

